package com.up.remoting.service.impl;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.activation.MimetypesFileTypeMap;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.google.gson.Gson;
import com.up.remoting.Constants;
import com.up.remoting.service.SubmitSDK;
import com.up.remoting.util.TypeUtils;
import com.up.remoting.util.URLBuilder;

/**
 * @author xueqiang.mi
 * 
 */
public class SubmitSDKImpl implements SubmitSDK {
  private static AbstractRemotingService remotingService;
  private static SubmitSDK instance;

  public static SubmitSDK getInstance() {
    if (instance == null) {
      if (remotingService == null) {
        throw new NullPointerException("Please initialize this SDK before using it.");
      }

      instance = new SubmitSDKImpl();
    }

    return instance;
  }

  public static void init(AbstractRemotingService remotingService) {
    SubmitSDKImpl.remotingService = remotingService;
  }

  private SubmitSDKImpl() {
  }

  @Override
  public int addComment(int itemId, String comment) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_COMMENT_ADD, itemId);
    HttpPost request = new HttpPost(uri);

    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    parameters.add(new BasicNameValuePair("comment", comment));

    try {
      request.setEntity(new UrlEncodedFormEntity(parameters, "utf-8"));
      DefaultHttpClient client = remotingService.getHttpClientCookied();
      HttpResponse response = client.execute(request);
      if (response.getStatusLine().getStatusCode() == 200) {
        String resp = EntityUtils.toString(response.getEntity());
        return parseResponse(resp);
      }
    } catch (Exception e) {
    }
    return 1;
  }

  @Override
  public int addFriend(int friendId) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_FRIEND_ADD, friendId);
    String resp = remotingService.get(uri);

    return parseResponse(resp);
  }

  @Override
  public int brandItem(int itemId, int brandId) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_ITEM_BRAND, itemId, brandId);
    String resp = remotingService.get(uri);

    return parseResponse(resp);
  }

  @Override
  public int changeAvatar(File file) {
    HttpPost request = new HttpPost(Constants.SUBMITSDK_API_AVATAR_CHANGE);
    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

    MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
    String mimeType = fileTypeMap.getContentType(file);
    FileBody fileBody = new FileBody(file, mimeType);
    entity.addPart("avatar", fileBody);

    request.setEntity(entity);
    DefaultHttpClient client = remotingService.getHttpClientCookied();
    try {
      HttpResponse response = client.execute(request);
      if (response.getStatusLine().getStatusCode() == 200) {
        String resp = EntityUtils.toString(response.getEntity());
        return parseResponse(resp);
      }
    } catch (Exception e) {
    }
    return 1;
  }

  @Override
  public int collectItem(int itemId) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_USER_COLLECT, itemId);
    String resp = remotingService.get(uri);

    return parseResponse(resp);
  }

  @Override
  public int deleteComment(int commentId) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_COMMENT_DEL, commentId);
    String resp = remotingService.get(uri);

    return parseResponse(resp);
  }

  @Override
  public int deleteFriend(int friendId) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_FRIEND_DEL, friendId);
    String resp = remotingService.get(uri);

    return parseResponse(resp);
  }

  @Override
  public int likeItem(int itemId) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_USER_LIKE, itemId);
    String resp = remotingService.get(uri);

    return parseResponse(resp);
  }

  @Override
  public int register(Map<String, String> data) {
    HttpPost request = new HttpPost(Constants.SUBMITSDK_API_USER_REGISTER);
    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    for (String key : data.keySet()) {
      parameters.add(new BasicNameValuePair(key, data.get(key)));
    }

    try {
      request.setEntity(new UrlEncodedFormEntity(parameters, "utf-8"));
      DefaultHttpClient client = remotingService.getHttpClient();
      HttpResponse response = client.execute(request);
      if (response.getStatusLine().getStatusCode() == 200) {
        String resp = EntityUtils.toString(response.getEntity());
        return parseResponse(resp);
      }
    } catch (Exception e) {
    }
    return 1;
  }

  @Override
  public int shareItem(int itemId, String content) {
    String uri = URLBuilder.build(Constants.SUBMITSDK_API_ITEM_SHARE, itemId);
    HttpPost request = new HttpPost(uri);

    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    parameters.add(new BasicNameValuePair("content", content));

    try {
      request.setEntity(new UrlEncodedFormEntity(parameters, "utf-8"));
      DefaultHttpClient client = remotingService.getHttpClientCookied();
      HttpResponse response = client.execute(request);
      if (response.getStatusLine().getStatusCode() == 200) {
        String resp = EntityUtils.toString(response.getEntity());
        return parseResponse(resp);
      }
    } catch (Exception e) {
    }
    return 1;
  }

  @Override
  public int submitMedia(int itemId, File file) {
    HttpPost request = new HttpPost(Constants.SUBMITSDK_API_ITEM_MEDIA);
    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

    MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
    String mimeType = fileTypeMap.getContentType(file);
    FileBody fileBody = new FileBody(file, mimeType);
    entity.addPart("media", fileBody);

    StringBody stringBody = null;
    try {
      stringBody = new StringBody(String.valueOf(itemId));
    } catch (UnsupportedEncodingException e) {
      return 1;
    }
    entity.addPart("item_id", stringBody);

    request.setEntity(entity);
    DefaultHttpClient client = remotingService.getHttpClientCookied();
    try {
      HttpResponse response = client.execute(request);
      if (response.getStatusLine().getStatusCode() == 200) {
        String resp = EntityUtils.toString(response.getEntity());
        Map<String, String> data = new Gson().fromJson(resp, TypeUtils.TYPE_MAP_STRING_STRING);
        if ("Y".equals(data.get("status"))) {
          return 0;
        }
        return 1;
      }
    } catch (Exception e) {
      return 1;
    }

    return 1;
  }

  @Override
  public int submitItem(Map<String, String> data) {
    HttpPost request = new HttpPost(Constants.SUBMITSDK_API_ITEM_SUBMIT);
    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    for (String key : data.keySet()) {
      parameters.add(new BasicNameValuePair(key, data.get(key)));
    }

    try {
      request.setEntity(new UrlEncodedFormEntity(parameters, "utf-8"));
      DefaultHttpClient client = remotingService.getHttpClientCookied();
      HttpResponse response = client.execute(request);
      if (response.getStatusLine().getStatusCode() == 200) {
        String resp = EntityUtils.toString(response.getEntity());
        Map<String, String> map = new Gson().fromJson(resp, TypeUtils.TYPE_MAP_STRING_STRING);
        if ("Y".equals(map.get("status"))) {
          String id = map.get("id");
          return Integer.valueOf(id);
        } else {
          return 0;
        }
      }
    } catch (Exception e) {
    }
    return 0;
  }

  private int parseResponse(String resp) {
    Map<String, String> map = new Gson().fromJson(resp, TypeUtils.TYPE_MAP_STRING_STRING);
    if ("Y".equals(map.get("status"))) {
      return 0;
    }

    return 1;
  }

}
